package ro.ubbcluj.cs.damate.ws.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ws.server.endpoint.annotation.Endpoint;
import org.springframework.ws.server.endpoint.annotation.PayloadRoot;
import org.springframework.ws.server.endpoint.annotation.RequestPayload;
import org.springframework.ws.server.endpoint.annotation.ResponsePayload;
import org.springframework.ws.transport.context.TransportContext;
import org.springframework.ws.transport.context.TransportContextHolder;
import org.springframework.ws.transport.http.HttpServletConnection;
import ro.ubbcluj.cs.damate.persistence.entities.Token;
import ro.ubbcluj.cs.damate.persistence.entities.User;
import ro.ubbcluj.cs.damate.services.TokenService;
import ro.ubbcluj.cs.damate.services.UserService;
import ro.ubbcluj.cs.damate.ws.generated.AuthenticationRequest;
import ro.ubbcluj.cs.damate.ws.generated.AuthenticationResponse;
import ro.ubbcluj.cs.damate.ws.generated.TokenValidationRequest;
import ro.ubbcluj.cs.damate.ws.generated.TokenValidationResponse;

import javax.servlet.http.HttpServletRequest;

/**
 * @author Lóránd Fazakas (lfazakas)
 *         Date: 2013.06.26.
 *         Time: 10:16
 */
@Endpoint
public class AuthenticationServiceEndpoint {

    private static final int AUTH_SUCCESSFUL = 200;
    private static final int USER_NOT_FOUND = 404;
    private static final int LOGIN_NOT_ALLOWED = 401;

    @Autowired
    private UserService userService;

    @Autowired
    private TokenService tokenService;

    @PayloadRoot(localPart="AuthenticationRequest", namespace = "http://cs.ubbcluj.ro/damate/ws")
    @ResponsePayload
    public AuthenticationResponse authenticate(@RequestPayload AuthenticationRequest message) {
        AuthenticationResponse response = new AuthenticationResponse();
        User user = userService.findByUsernameAndPassword(message.getUsername(), message.getPassword());
        if (user != null && user.isState()) {
            Token token = tokenService.createNewToken(user, getClientAddress());
            response.setToken(token.getToken());
            response.setResponseStatusCode(AUTH_SUCCESSFUL);
        } else if (user == null) {
            response.setResponseStatusCode(USER_NOT_FOUND);
        } else {
            response.setResponseStatusCode(LOGIN_NOT_ALLOWED);
        }
        return response;
    }

    @PayloadRoot(localPart="TokenValidationRequest", namespace = "http://cs.ubbcluj.ro/damate/ws")
    @ResponsePayload
    public TokenValidationResponse validateToken(@RequestPayload TokenValidationRequest message) {
        TokenValidationResponse response = new TokenValidationResponse();
        response.setValid(false);
        if (tokenService.isValidToken(message.getToken(), getClientAddress())) {
            response.setValid(true);
        }
        return response;
    }

    private String getClientAddress() {
        TransportContext context = TransportContextHolder.getTransportContext();
        HttpServletConnection connection = (HttpServletConnection)context.getConnection();
        HttpServletRequest request = connection.getHttpServletRequest();
        return request.getRemoteAddr();
    }
}
